home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / HUGEREAD.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  4KB  |  158 lines

  1. /*
  2. **  HUGEREAD.C - "Universal" PC read and write functions using huge data
  3. **               and far pointers.
  4. **
  5. **  NOTES:
  6. **
  7. **  1. If these functions are called with a prototype in scope, passed
  8. **     parameters will be coerced to the proper data types.
  9. **
  10. **  2. Since these call read() and write(), all normal mode flags which
  11. **     are supported by individual compilers will be honored.
  12. **
  13. **  3. In small data memory models (S, T, and M), an intermediate buffer
  14. **     is allocated and used. In large data models (L and C), the data
  15. **     are read/written directly from/to target memory.
  16. **
  17. **  4. Like many mixed-model functions, this may generate lots of warnings
  18. **     with many compilers. Despite this, it really does generate correct
  19. **     code for all major PC compilers.
  20. **
  21. **  Original Copyright 1992 by Bob Stout as part of
  22. **  the MicroFirm Function Library (MFL)
  23. **
  24. **  This subset version is hereby donated to the public domain.
  25. */
  26.  
  27. #include <dos.h>
  28. #include <io.h>
  29. #include <stdlib.h>
  30. #include <stddef.h>
  31.  
  32. #ifdef __TURBOC__
  33.  #define FAR far
  34. #else
  35.  #define FAR _far
  36. #endif
  37.  
  38. #ifndef min
  39.  #define min(x,y) (((x) <= (y)) ? (x) : (y))
  40. #endif
  41.  
  42. #ifndef MK_FP
  43.  #define MK_FP(seg,offset) \
  44.         ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
  45. #endif
  46.  
  47. /*
  48. **  Get the largest buffer possible.
  49. */
  50.  
  51. static size_t gettmp(char **buf)
  52. {
  53.       size_t bufsiz;
  54.  
  55.       for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
  56.       {
  57.             if (NULL != (*buf = (char *) malloc(bufsiz)))
  58.                   return bufsiz;
  59.       }
  60.       return 0;
  61. }
  62.  
  63. /*
  64. **  Normalize a far pointer
  65. */
  66.  
  67. void FAR *farnormal(void FAR *ptr)
  68. {
  69.       size_t seg, ofs;
  70.  
  71.       seg = FP_SEG(ptr);
  72.       ofs = FP_OFF(ptr);
  73.       return MK_FP(seg + (ofs >> 4), ofs & 0xf);
  74. }
  75.  
  76. /*
  77. **  Read any size block to anywhere in memory
  78. */
  79.  
  80. long hugeread(int fh, char FAR *buf, long size)
  81. {
  82.       long count;
  83.       size_t bufsiz;
  84.       char *tmp;
  85.       long ercode = size;
  86.  
  87.       if (4 > sizeof(void *))
  88.       {
  89.             if (0 == (bufsiz = gettmp(&tmp)))
  90.                   return -1L;
  91.       }
  92.       else
  93.       {
  94.             tmp = (char *)buf;
  95.             bufsiz = 0x4000;
  96.       }
  97.  
  98.       while (0 < (count = min(size, (long)bufsiz)))
  99.       {
  100.             int i, numread = read(fh, tmp, (size_t)count);
  101.  
  102.             if (1 > numread || numread != (int)count)
  103.                   return -1L;
  104.             if (4 > sizeof(void *))
  105.             {
  106.                   for (i = 0; i < count; ++i)
  107.                         buf[i] = tmp[i];
  108.             }
  109.             buf = farnormal(buf + count);
  110.             size -= count;
  111.             if (2 < sizeof(void *))
  112.                   tmp = (char *)buf;
  113.       }
  114.       return ercode;
  115. }
  116.  
  117. /*
  118. **  Write any size block from anywhere in memory
  119. */
  120.  
  121. long hugewrite(int fh, char FAR *buf, long size)
  122. {
  123.       long count;
  124.       size_t bufsiz;
  125.       char *tmp;
  126.       long ercode = size;
  127.  
  128.       if (4 > sizeof(void *))
  129.       {
  130.             if (0 == (bufsiz = gettmp(&tmp)))
  131.                   return -1L;
  132.       }
  133.       else
  134.       {
  135.             tmp = (char *)buf;
  136.             bufsiz = 0x4000;
  137.       }
  138.  
  139.       while (0 < (count = min(size, (long)bufsiz)))
  140.       {
  141.             int i, numwrite;
  142.  
  143.             if (4 > sizeof(void *))
  144.             {
  145.                   for (i = 0; i < count; ++i)
  146.                         tmp[i] = buf[i];
  147.             }
  148.             numwrite = write(fh, tmp, (size_t)count);
  149.             if (1 > numwrite || numwrite != (int)count)
  150.                   return -1L;
  151.             buf = farnormal(buf + count);
  152.             size -= count;
  153.             if (2 < sizeof(void *))
  154.                   tmp = (char *)buf;
  155.       }
  156.       return ercode;
  157. }
  158.